﻿using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.ServiceModel;
using System.ServiceModel.Configuration;
using System.ServiceModel.Channels;

namespace WU.LoadTester.Lib.Service.Bindings
{
    public class CustomAsmxBinding : CustomBinding
    {
        public CustomAsmxBinding(CustomBindingElement element)
        {
            this.CloseTimeout = element.CloseTimeout;
            this.OpenTimeout = element.OpenTimeout;
            this.ReceiveTimeout = element.ReceiveTimeout;
            this.SendTimeout = element.SendTimeout;

            var encoding = this.GetEncodingElement(element);
            this.Elements.Add(encoding);
            var transport = this.GetTransportElement(element);
           this.Elements.Add(transport);
        }

        private TextMessageEncodingBindingElement GetEncodingElement(CustomBindingElement element)
        {
            var encoding = new TextMessageEncodingBindingElement();
            try
            {
                var encodingElement =
                    (TextMessageEncodingElement)
                    element.Single(e => e is TextMessageEncodingElement);
                encoding.MaxReadPoolSize = encodingElement.MaxReadPoolSize;
                encoding.MaxWritePoolSize = encodingElement.MaxWritePoolSize;
                encoding.MessageVersion = encodingElement.MessageVersion;
                encoding.WriteEncoding = encodingElement.WriteEncoding;
            }
            catch
            {
                encoding.MaxReadPoolSize = 64;
                encoding.MaxWritePoolSize = 16;
                encoding.MessageVersion = MessageVersion.Soap12;
                encoding.WriteEncoding = System.Text.Encoding.UTF8;
            }
            return encoding;
        }
        private HttpTransportBindingElement GetTransportElement(CustomBindingElement element)
        {
            var transport = new HttpTransportBindingElement();
            try
            {
                var transportElement = (HttpTransportElement) element.Single(e => e is HttpTransportElement);
                transport.AllowCookies = transportElement.AllowCookies;
                transport.AuthenticationScheme = transportElement.AuthenticationScheme;
                transport.BypassProxyOnLocal = transportElement.BypassProxyOnLocal;
                transport.DecompressionEnabled = transportElement.DecompressionEnabled;
                transport.HostNameComparisonMode = transportElement.HostNameComparisonMode;
                transport.KeepAliveEnabled = transportElement.KeepAliveEnabled;
                transport.ManualAddressing = transportElement.ManualAddressing;
                transport.MaxBufferPoolSize = transportElement.MaxBufferSize;
                transport.MaxPendingAccepts = transportElement.MaxPendingAccepts;
                transport.MaxReceivedMessageSize = transportElement.MaxReceivedMessageSize;
                transport.ProxyAddress = transportElement.ProxyAddress;
                transport.ProxyAuthenticationScheme = transportElement.ProxyAuthenticationScheme;
                transport.UseDefaultWebProxy = transportElement.UseDefaultWebProxy;
                transport.Realm = transportElement.Realm;
                transport.RequestInitializationTimeout = transportElement.RequestInitializationTimeout;
                transport.TransferMode = transportElement.TransferMode;
                transport.UnsafeConnectionNtlmAuthentication = transportElement.UnsafeConnectionNtlmAuthentication;
                transport.UseDefaultWebProxy = transportElement.UseDefaultWebProxy;
                transportElement.WebSocketSettings.InitializeFrom(transport.WebSocketSettings);
            }
            catch
            {
                transport.AuthenticationScheme = AuthenticationSchemes.Anonymous;
                transport.ManualAddressing = false;
                transport.AllowCookies = false;
                transport.BypassProxyOnLocal = false;
                transport.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
                transport.UseDefaultWebProxy = true;
                transport.UnsafeConnectionNtlmAuthentication = false;
            }
            return transport;
        }
    }
}
